<template>
  <span v-if="$slots?.trigger" @click="handleOpen">
    <slot name="trigger"></slot>
  </span>
  <a-modal
    :visible="visible"
    :width="width"
    :title="title || '提示'"
    :ok-button-props="okButtonProps"
    :title-align="titleAlign"
    :mask-closable="maskClosable"
    :hide-title="hideTitle"
    :closable="closable"
    :ok-text="okText || '确定'"
    :cancel-text="cancelText || '取消'"
    :esc-to-close="escClose"
    :hide-cancel="hideCancel"
    :popup-container="popupContainer"
    :on-before-ok="handleBeforeOk"
    :unmount-on-close="unmountOnClose"
    :modal-class="modalClass"
    :body-class="bodyClass"
    :modal-style="modalStyle"
    :ok-loading="loading"
    :footer="footer"
    @before-open="handleOpen"
    @cancel="handleCancel"
    @ok="ok"
    @open="open"
    @before-close="beforeClose">
    <template #title>
      <div v-if="!!icon" class="flex items-center gap-2">
        <icon-info-circle-fill
          v-if="icon === 'warning'"
          class="text-base"
          :class="iconColor ? 'text-danger!' : 'text-warning!'" />
        <slot name="title">{{ title }}</slot>
      </div>
      <slot v-else name="title"></slot>
    </template>
    <template #footer>
      <slot name="footer"></slot>
    </template>
    <slot></slot>
  </a-modal>
</template>
<script lang="ts" setup>
import type { ButtonProps } from '@arco-design/web-vue'
import { IconInfoCircleFill } from '@arco-design/web-vue/es/icon'
import type { CSSProperties } from 'vue'
interface IProps {
  title?: string
  icon?: 'warning'
  iconColor?: boolean
  titleAlign?: 'start' | 'center'
  width?: number | string
  hideCancel?: boolean
  okButtonProps?: Partial<ButtonProps>
  closable?: boolean
  hideTitle?: boolean
  okText?: string
  cancelText?: string
  footer?: boolean
  maskClosable?: boolean
  escClose?: boolean
  popupContainer?: string
  unmountOnClose?: boolean
  dialogClass?: string | any[]
  bodyClass?: string | any[]
  danger?: boolean
  loading?: boolean
  modalStyle?: CSSProperties
  beforeOk?: () => Promise<any>
  beforeOpen?: () => Promise<any>
  open?: () => void
  cancel?: () => void
  ok?: () => void
  beforeClose?: () => void
}
const props = withDefaults(defineProps<IProps>(), {
  title: '',
  titleAlign: 'start',
  iconColor: false,
  width: 450,
  hideCancel: false,
  closable: true,
  hideTitle: false,
  okText: '',
  cancelText: '',
  footer: true,
  maskClosable: false,
  escClose: false,
  popupContainer: 'body',
  unmountOnClose: true,
  dialogClass: '',
  bodyClass: 'basic-dialog__body',
  modalStyle: undefined,
  danger: false,
  loading: false,
  open: undefined
})
//local:true表示如果引用多个子组件，值不共享，默认为false
const visible = defineModel<boolean>('visible', { local: true, default: false })

const handleOpen = async () => {
  if (props.beforeOpen) {
    try {
      const res = await props.beforeOpen()
      return res
    } catch (error) {
      console.error(error)

      visible.value = false
    }
  } else {
    visible.value = true
  }
}
const handleBeforeOk = async () => {
  try {
    const res = await props.beforeOk?.()
    if (res === false) return false
    handleCancel()
    return res
  } catch (error) {
    console.error(error)
    return false
  }
}
const handleCancel = () => {
  if (props.cancel) {
    props.cancel()
  }

  visible.value = false
}

const modalClass = computed<string | any[]>(() => {
  const basic = props.danger
    ? 'basic-dialog is-danger'
    : 'basic-dialog is-normal'

  if (Array.isArray(props.dialogClass)) {
    return [basic, ...props.dialogClass]
  } else {
    return basic + ' ' + props.dialogClass
  }
})
</script>
